package com.mingqijia.gassafety.job.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.gap.cache.redis.RedisCache;
import com.mingqijia.gassafety.db.entity.*;
import com.mingqijia.gassafety.db.entity.vo.ConsumerStrategyVo;
import com.mingqijia.gassafety.db.mapper.*;
import com.mingqijia.gassafety.job.dto.SendMessageDTO;
import com.mingqijia.gassafety.job.service.ConsumerService;
import com.mingqijia.gassafety.shared.constant.*;
import com.mingqijia.gassafety.shared.dto.AssembleTemplateDTO;
import com.mingqijia.gassafety.shared.dto.TaskDetailParamDTO;
import com.mingqijia.gassafety.shared.dto.TaskDetailRespDTO;
import com.mingqijia.gassafety.shared.utils.RedisCacheExt;
import com.mingqijia.gassafety.shared.utils.commonUtils.DateUtils;
import com.mingqijia.gassafety.shared.utils.commonUtils.SnowflakeUtil;
import com.mingqijia.gassafety.shared.utils.message.SendMessageService;
import com.mingqijia.gassafety.shared.vcc.VccAuthoritiesProvider;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;


/**
 * @author zhangfei
 * @version 1.0.0
 * @ClassName RunningStrategyServiceImpl.java
 * @Description
 * @createTime 2023年12月19日
 */

@Component
@Slf4j
public class RunningStrategyServiceImpl {

    @Autowired
    RedisCache redisCache;
    @Autowired
    ConsumerMapper consumerMapper;
    @Autowired
    CustomerSubsMapper customerSubsMapper;
    @Autowired
    DtuMapper dtuMapper;
    @Autowired
    RunningStrategyExtMapper extMapper;
    @Autowired
    ContactsMapper contactsMapper;
    @Autowired
    SendMessageService sendMessageService;
    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    DictionaryMapper dictionaryMapper;
    @Autowired
    RunningStrategyMapper warnStrategyMapper;

    @Autowired
    EquipmentServiceImpl equipmentService;
    @Autowired
    CompanyServiceImpl companyService;

    @Autowired
    DevicebindingServiceImpl devicebindingService;
    @Autowired
    BusinessNoticeMapper noticeMapper;

    @Autowired
    InformRecordMapper informRecordMapper;
    @Autowired
    RunningRecordMapper runningRecordMapper;
    @Autowired
    ReceiverValveMapper receiverValveMapper;
    public static final String split = ";";
    public static final String split_ = "-";
    //可偏移的毫秒值，范围为<=
    private final Integer offsetRangeConstant = 150000;
    private final Integer MaxRangeConstant = 600000;

    public static final String CM_SERVICE_HOT_LINE = "cm_service_hot_line";

    public static final String OUTBOUND_CALL_CHANNEL_SETTINGS = "outbound_call_channel_settings";

    @Value(value = "${gassafety.warnStrategy.switch}")
    private boolean sw;
    @Autowired
    RedisCacheExt redisUtil;

    @Autowired
    VccAuthoritiesProvider provider;

    @Autowired
    DeviceStateMapper deviceStateMapper;
    @Autowired
    DtuBindingOrderMapper dtuBindingOrderMapper;
    @Autowired
    ConsumerService consumerService;
    @Autowired
    CallTaskServiceImpl callTaskService;
    @Autowired
    RecordReceiverValveMapper recordReceiverValveMapper;


    public void routeReport(Map<String, Object> dtuMap,  long snowflakeId,
                            String con, List<Map<String, Object>> list, Object strategyId, List<RunningStrategyExt> exts,
                            Date date, Map<String, Object> assembleTemplate, List<String> adviceTypes, String spId) {
        // 1 短信推送 2 微信模版消息 3机器人外呼
        if (adviceTypes.contains("1")) {
            log.info("runningRoute----start:{}", "发送短信");
            List<RunningStrategyExt> collect = exts.stream().filter(warnStrategyExt -> {
                return warnStrategyExt.getPushType() == 1;
            }).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(collect)) {
                RunningStrategyExt ext = collect.get(0);
                //获取间隔对应值
                Map<String, Object> res = sendMessage(3, list, ext, new HashMap<>(), date,
                        (Map<String, Object>) assembleTemplate.get("param"), spId , "", 2, con, strategyId,
                        snowflakeId, assembleTemplate.get("SMSMessage") + "",
                        "", dtuMap.get("cust_name") + "(" + dtuMap.get("subs_code") + ")", "");
                log.info("runningRoute----res:{}", JSONObject.toJSONString(res));
            }
        }
        int type = 0;
        if (adviceTypes.contains("2")) {
            log.info("runningRoute----start:{}", "发送微信消息");
            List<RunningStrategyExt> collect = exts.stream().filter(warnStrategyExt -> {
                return warnStrategyExt.getPushType() == 2;
            }).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(collect)) {
                RunningStrategyExt ext = collect.get(0);
                if (!StringUtils.isEmpty(dtuMap.get("subs_code"))) {
                    LambdaQueryWrapper<CustomerSubs> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                    lambdaQueryWrapper.eq(CustomerSubs::getIsDeleted, 0)
                            .eq(CustomerSubs::getBandingStatus, 1)
                            .eq(CustomerSubs::getSubsCode, dtuMap.get("subs_code"));
                    if (!CollectionUtil.isEmpty(customerSubsMapper.selectList(lambdaQueryWrapper))) {
                        //调用外部微信接口
                        type = -1;
                        Map<String, Object> resWx = sendWxMessage(3, date, ext, (Map<String, Object>) assembleTemplate.get("wxParam"), new HashMap<>(), dtuMap,
                                "", 2, con, strategyId, snowflakeId, assembleTemplate.get("wxMessage") + "",
                                "", type);

                        log.info("runningRoute----resWx:{}", JSONObject.toJSONString(resWx));
                    }
                }
            }
        }
        if (adviceTypes.contains("3")) {
            //发送外呼消息
            log.info("runningRoute----start:{}", "发送外呼消息");
            List<RunningStrategyExt> collect = exts.stream().filter(warnStrategyExt -> {
                return warnStrategyExt.getPushType() == 3;
            }).collect(Collectors.toList());
            log.info("runningRoute----ext:{}", JSONObject.toJSONString(collect));
            if (!CollectionUtils.isEmpty(collect)) {
                RunningStrategyExt ext = collect.get(0);
                    Map<String, Object> res = callMessage(3, list, ext, new HashMap<>(), date,
                            spId, "",2, con, strategyId, snowflakeId,
                            "", dtuMap.get("cust_name") + "(" + dtuMap.get("subs_code") + ")", dtuMap.get("equipment_type") + "");
                    log.info("runningRoute----res:{}", JSONObject.toJSONString(res));
            }
        }
    }

    //存储报警记录
    public void saveRunningRecord(String spId, String iMEI,
                                  int report, String con, Object strategyId,
                                  String level, Date date, int sendType, long snowflakeId, int sendResult,
                                  String content, String supIMEI, Object errorMsg,
                                  String receiptCode, String telephone, int type, String info) {

        RunningRecord warningRecord = new RunningRecord();
        warningRecord.setConsumerId(con);
        warningRecord.setStartTime(date);
        warningRecord.setEndTime(date);
        warningRecord.setTriggerRuleId(Long.parseLong(strategyId + ""));
        warningRecord.setTaskIdentificationCode(snowflakeId + "");
        warningRecord.setSendType(sendType);
        warningRecord.setObjLevel(level);
        warningRecord.setSpId(spId);
        warningRecord.setSendResult(sendResult);
        warningRecord.setContent(content);
        warningRecord.setReceiptCode(receiptCode);
        warningRecord.setPushPhone(telephone);
        warningRecord.setStatus(1);
        warningRecord.setRemark(!StringUtils.isEmpty(errorMsg) ? errorMsg + "" : "发送成功");
        log.info("saveRunningRecord:{}", JSONObject.toJSONString(warningRecord));
        runningRecordMapper.insert(warningRecord);
    }




    public void route(Map<String, Object> dtuMap, String iMEI, String subId, int report, long snowflakeId,
                       String con, List<Map<String, Object>> list, Object strategyId, List<RunningStrategyExt> exts,
                       Map<String, Object> dataMap, Date date, Map<String, Object> assembleTemplate, List<String> adviceTypes ,String key
            ,boolean nextSend,boolean nextWx,boolean nextCall) {

        try {
            Map<String, Object> o = redisCache .getCacheMap(key);
            log.info("running-获取发送次数:{}", JSONObject.toJSONString(o));
            dtuMap.put("cust_name", StringUtils.isEmpty(dtuMap.get("cust_name")) ? dtuMap.get("custName") : dtuMap.get("cust_name"));
            dtuMap.put("subs_code", StringUtils.isEmpty(dtuMap.get("subs_code")) ? dtuMap.get("memberId") : dtuMap.get("subs_code"));
            Integer sendInterval = 0;
            // 1 短信推送 2 微信模版消息 3机器人外呼
            if (adviceTypes.contains("1")&&!nextSend) {
                log.info("runningRoute----start:{}", "发送短信");
                List<RunningStrategyExt> collect = exts.stream().filter(warnStrategyExt -> {
                    return warnStrategyExt.getPushType() == 1;
                }).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(collect)) {
                    RunningStrategyExt ext = collect.get(0);
                    sendInterval = ext.getPushFrequency();
                    dataMap.put("level", ext.getPushLevel());
                    //获取间隔对应值
                    if (o!=null&&o.size()>0&&Integer.parseInt(o.get("count_m")+"")>ext.getPushNumber()){
                        saveWarningRecord(ext.getSpId(), iMEI, report, con, strategyId,
                                ext.getPushLevel(), date, 1, snowflakeId, 1, "",
                                "", "此规则推送次数已超限","", "", 0, "");
                    }else {
                        Map<String, Object> res = sendMessage(sendInterval, list, ext, dataMap, date,
                                (Map<String, Object>) assembleTemplate.get("param"), dtuMap.get("sp_id") + "", subId.equals("1-0") ? iMEI : (iMEI + "-" + subId), report, con, strategyId,
                                snowflakeId, assembleTemplate.get("SMSMessage") + "",
                                iMEI, dtuMap.get("cust_name") + "(" + dtuMap.get("subs_code") + ")",key);
                        log.info("runningRoute----res:{}", JSONObject.toJSONString(res));
                        if (!res.get("res").equals("no")) {
                            dataMap.put("count_m",o==null||o.size()<0||o.get("count_m")==null
                                    ?1:Integer.parseInt(o.get("count_m")+"")+1);
                        }
                    }

                }
            }
            int type = 0;
            if (adviceTypes.contains("2")&&!nextWx) {
                log.info("runningRoute----start:{}", "发送微信消息");
                List<RunningStrategyExt> collect = exts.stream().filter(warnStrategyExt -> {
                    return warnStrategyExt.getPushType() == 2;
                }).collect(Collectors.toList());
                if (!CollectionUtils.isEmpty(collect)) {
                    RunningStrategyExt ext = collect.get(0);
                    sendInterval = ext.getPushFrequency();
                    if (!StringUtils.isEmpty(dtuMap.get("subs_code"))) {
                        LambdaQueryWrapper<CustomerSubs> lambdaQueryWrapper = new LambdaQueryWrapper<>();
                        lambdaQueryWrapper.eq(CustomerSubs::getIsDeleted, 0)
                                .eq(CustomerSubs::getBandingStatus, 1)
                                .eq(CustomerSubs::getSubsCode, dtuMap.get("subs_code"));
                        List<CustomerSubs> customerSubs = customerSubsMapper.selectList(lambdaQueryWrapper);
                        log.info("customerSubs:{}",JSONObject.toJSONString(customerSubs));
                        if (!CollectionUtil.isEmpty(customerSubs)) {
                            //调用外部微信接口
                            type = -1;

                            if (o!=null&&o.size()>0&&Integer.parseInt(o.get("count_w")+"")>ext.getPushNumber()){
                                saveWarningRecord(ext.getSpId(), iMEI, report, con, strategyId,
                                        ext.getPushLevel(), date, 2, snowflakeId, 1, "",
                                        "", "此规则推送次数已超限","", "", 0, "");
                            }else {
                                Map<String, Object> resWx = sendWxMessage(sendInterval, date, ext, (Map<String, Object>) assembleTemplate.get("wxParam"), dataMap, dtuMap,
                                        subId.equals("1-0") ? iMEI : (iMEI + "-" + subId), report, con, strategyId,
                                        snowflakeId, assembleTemplate.get("wxMessage") + "",
                                        iMEI, type);
                                log.info("runningRoute----resWx:{}", JSONObject.toJSONString(resWx));
                                if (!resWx.get("res").equals("no")) {
                                    dataMap.put("count_w", o == null || o.get("count_w") == null ? 1 : Integer.parseInt(o.get("count_w")+"") + 1);
                                }
                            }
                        }
                    }
                }
            }
            if (adviceTypes.contains("3")&&!nextCall) {
                //发送外呼消息
                log.info("runningRoute----start:{}", "发送外呼消息");
                List<RunningStrategyExt> collect = exts.stream().filter(warnStrategyExt -> {
                    return warnStrategyExt.getPushType() == 3;
                }).collect(Collectors.toList());
                log.info("runningRoute----ext:{}", JSONObject.toJSONString(collect));
                if (!CollectionUtils.isEmpty(collect)) {
                    RunningStrategyExt ext = collect.get(0);
                    sendInterval = ext.getPushFrequency();
                    dataMap.put("level", ext.getPushLevel());
                    if (o!=null&&o.size()>0&&Integer.parseInt(o.get("count_c")+"") > ext.getPushNumber()) {
                        saveWarningRecord(ext.getSpId(), iMEI, report, con, strategyId,
                                ext.getPushLevel(), date, 3, snowflakeId, 1, "",
                                "", "此规则推送次数已超限", "", "", 0, "");
                    } else {
                        Map<String, Object> res = callMessage(sendInterval, list, ext, dataMap, date,
                                dtuMap.get("sp_id") + "", subId.equals("1-0") ? iMEI : (iMEI + "-" + subId),
                                report, con, strategyId, snowflakeId,
                                iMEI, dtuMap.get("cust_name") + "(" + dtuMap.get("subs_code") + ")", dtuMap.get("equipment_type") + "");
                        log.info("runningRoute----res:{}", JSONObject.toJSONString(res));
                        if (!res.get("res").equals("no")) {
                            dataMap.put("count_c", o == null || o.get("count_c") == null ? 1 : Integer.parseInt(o.get("count_c")+"") + 1);
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("runningRoute-error:{}", e);
        }
    }


    private void pushWx(Map<String, Object> param, String spId, String iMEI, int report,
                        String con, Object strategyId, Date date,
                        long snowflakeId, String content, String supIMEI
            , String custName, String custCode, List<String> phones, int type, String level) {

        log.info("pushWx-wx-phones:{}", JSONObject.toJSONString(phones));
        String orgCode = companyService.getOrgCode(spId, con);
        log.info("pushWx-wx-orgCode:{}", JSONObject.toJSONString(orgCode));
        Map<String, Object> sms = sendMessageService
                .sendSms(sendMessageService
                                .getRequestParam(null
                                        , WxTypeEnum.getPushTypes(report).getName(), orgCode
                                        , param, "wxtpl", new ArrayList<>(), type == -1 ? custCode : null, phones, 0)
                        , "");

        if (sms.get("result").equals(true)) {
            //发送成功
            String errorMsg = "发送成功";
            if (sms.get("data") != null) {
                HashMap<String, Object> req = new HashMap<>();
                req.put("ids", sms.get("data"));
                req.put("orgCode", orgCode);
                try {
                    Thread.sleep(2000L);
                    Map<String, Object> resMap = sendMessageService.subTaskDetail(req, "");
                    //延迟获取数据
                    errorMsg = resMap != null ? (String) resMap.get("errorMsg") : "";
                } catch (InterruptedException e) {
                    log.error("subTaskDetail-error:{}", e);
                }

                log.info("sendWxMessageAgain-微信消息发送人:{},发送结果:{}",
                        JSONObject.toJSONString(phones),
                        JSONObject.toJSONString(errorMsg));
            }
            saveWarningRecord(spId, iMEI, report, con, strategyId,
                    level, date, 2, snowflakeId, !StringUtils.isEmpty(errorMsg) ? 1 : 0, content,
                    supIMEI, errorMsg, JSONObject.toJSONString(sms.get("data")), !CollectionUtil.isEmpty(phones) ? phones.get(0) : "", 2, custName + "(" + custCode + ")");
        } else {
            String errorMsg = (String)sms.get("errMsg");
            saveWarningRecord(spId, iMEI, report, con, strategyId,
                    level, date, 2, snowflakeId, !StringUtils.isEmpty(errorMsg) ? 1 : 0, content,
                    supIMEI, errorMsg, JSONObject.toJSONString(sms.get("data")), !CollectionUtil.isEmpty(phones) ? phones.get(0) : "", 2, custName + "(" + custCode + ")");
        }
    }




    public Map<String, Object> getAssembleTemplate(AssembleTemplateDTO assembleTemplate, Integer type) {
        String orgCode = companyService.getOrgCode(assembleTemplate.getSpId(), (String) assembleTemplate.getConsumerId());
        assembleTemplate.setOrgCode(orgCode);

        int report = assembleTemplate.getReport();
        String phone = assembleTemplate.getPhone();
        String imei = assembleTemplate.getImei();
        String equipmentType = assembleTemplate.getEquipmentType();
        String installationPosition = assembleTemplate.getInstallationPosition();
        String consumerName = assembleTemplate.getConsumerName();
        String equipmentName = assembleTemplate.getEquipmentName();
        String custAddress = assembleTemplate.getCustAddress();
        Object consumerId = assembleTemplate.getConsumerId();
        String custName =assembleTemplate.getCustName();
        String subsCode = assembleTemplate.getSubsCode();

        QueryWrapper<DtuBindingOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.lambda().or().eq(DtuBindingOrder::getIsDeleted, 0)
                .eq(DtuBindingOrder::getConsumerId, consumerId);
        List<DtuBindingOrder> dtuBindingOrders = dtuBindingOrderMapper.selectList(orderQueryWrapper);
        String userID = "";
        String name = "";
        String address = "";
        if (!CollectionUtil.isEmpty(dtuBindingOrders)) {
            DtuBindingOrder dtuBindingOrder = dtuBindingOrders.get(0);
            address = StringUtils.isEmpty(dtuBindingOrder.getAddress()) ? dtuBindingOrder.getRealAddress() : dtuBindingOrder.getAddress();
            userID = dtuBindingOrder.getMemberId() + "";
            name = dtuBindingOrder.getCustName();
        } else {
            address = custAddress + "";
        }
        custName = custName == null ? "" : custName;
        subsCode = subsCode == null ? "" : subsCode;
        equipmentName = StringUtils.isEmpty(equipmentName) ? "" : equipmentName;
        Map<String, Object> resultMap = new HashMap<>();
        String format = DateUtil.format(new Date(), "yyyy-MM-dd HH:mm:ss");
        String SMSMessage ="";
        Map<String, Object> param = new HashMap<>();
        if (type==0){
            param.put("Time", format);
            param.put("position", installationPosition);
            param.put("IMEI", imei);
            param.put("phone", phone);
            param.put("address", address);
            param.put("subsName", custName);
            param.put("CustomerName", consumerName);
            param.put("smsMsgCode", assembleTemplate.getSmsMsgCode());
            if (report==1){
                SMSMessage = sendMessageService.getSmsContent(Constants.RUNNING_STRATEGY_FAULT,param,assembleTemplate);
            }else {
                SMSMessage = sendMessageService.getSmsContent(Constants.RUNNING_STRATEGY_OFFLINE,param,assembleTemplate);
            }
        }else {
            String date = DateUtil.format(DateUtil.offsetMonth(new Date(), -1), "yyyy年MM月");
            param.put("Date", date);
            param.put("phone", phone);
            param.put("address", address);
            param.put("subsName", custName);
            param.put("CustomerName", consumerName);
            param.put("smsMsgCode", assembleTemplate.getSmsMsgCode());
            SMSMessage = sendMessageService.getSmsContent(Constants.RUNNING_STRATEGY_REPORT,param,assembleTemplate);
        }
        Map<String, Object> wxParam = new HashMap<>();
        String wxMessage ="";
        String subConsumerName = consumerName.substring(0, Math.min(20, consumerName.length()));
        String subAddress = address.substring(0, Math.min(20, address.length()));
        String subsName = custName.length() < 20 - subsCode.length() ? custName : custName.substring(0, 15 - subsCode.length()) + "...";
        if (type==0){
          wxParam.put("Time", format);
          wxParam.put("position", installationPosition);
          wxParam.put("Equipmenttype", EquipmentTypeConst.equipmentTypeMaps.get(equipmentType));
          wxParam.put("IMEI", imei);
          wxParam.put("Equipment_status", "报警");
          wxParam.put("phone", phone);
          wxParam.put("EquipmentName", equipmentName + "");
          wxParam.put("Name", name);
          wxParam.put("UserID", userID);
          wxParam.put("address", subAddress);
          wxParam.put("subsName", subsName);
          wxParam.put("subsCode", subsCode);
          wxParam.put("CustomerName", subConsumerName);
          wxParam.put("wxMsgCode", assembleTemplate.getWxMsgCode());
//          //微信模板消息 WARNING_WX_MESSAGES
//           wxMessage = Constants.WARNING_WX_MESSAGES.replace("#Time#",
//                  format)
//                  .replace("#EquipmentName#", equipmentName + "")
//                  .replace("#position#", installationPosition + "")
//                  .replace("#IMEI#", imei)
//                  .replace("#Equipment_status#", "报警")
//                  .replace("#phone#", phone);

          if (report==1){
              //微信模板消息 WARNING_WX_MESSAGES
              wxMessage = sendMessageService.getWxContent(Constants.RUNNING__WX_STRATEGY_FAULT,wxParam,assembleTemplate);
          }else {
              //微信模板消息 WARNING_WX_MESSAGES
              wxMessage = sendMessageService.getWxContent(Constants.RUNNING__WX_STRATEGY_OFFLINE,wxParam,assembleTemplate);
          }

      }else {
          String date = DateUtil.format(DateUtil.offsetMonth(new Date(), -1), "yyyy年MM月");
          wxParam.put("Date", date);
          wxParam.put("address", subAddress);
          wxParam.put("subsName", subsName);
          wxParam.put("subsCode", subsCode);
          wxParam.put("IMEI", subsCode);
          wxParam.put("CustomerName", subConsumerName);
          wxParam.put("wxMsgCode", assembleTemplate.getWxMsgCode());
          //微信模板消息 WARNING_WX_MESSAGES
          wxMessage = sendMessageService.getWxContent(Constants.RUNNING__WX_STRATEGY_REPORT,wxParam,assembleTemplate);
      }
        resultMap.put("SMSMessage", SMSMessage);
        resultMap.put("param", param);
        resultMap.put("wxParam", wxParam);
        resultMap.put("wxMessage", wxMessage);
        log.info("SMSMessage:{}wxMessage:{}", param, wxParam);
        return resultMap;
    }

    public Map<String, Object> getServicePeriodTemplate(String verb, String endDate, String phone, String imei, Object installationPosition, Object equipmentName,
                                                        Object custAddress, Object consumerId, String custName, String subsCode) {

        QueryWrapper<DtuBindingOrder> orderQueryWrapper = new QueryWrapper<>();
        orderQueryWrapper.lambda().or().eq(DtuBindingOrder::getIsDeleted, 0)
                .eq(DtuBindingOrder::getConsumerId, consumerId);
        List<DtuBindingOrder> dtuBindingOrders = dtuBindingOrderMapper.selectList(orderQueryWrapper);
        String userID = "";
        String name = "";
        String address = "";
        if (!CollectionUtil.isEmpty(dtuBindingOrders)) {
            DtuBindingOrder dtuBindingOrder = dtuBindingOrders.get(0);
            address = StringUtils.isEmpty(dtuBindingOrder.getAddress()) ? dtuBindingOrder.getRealAddress() : dtuBindingOrder.getAddress();
            userID = dtuBindingOrder.getMemberId() + "";
            name = dtuBindingOrder.getCustName();
        } else {
            address = custAddress + "";
        }
        custName = custName == null ? "" : custName;
        subsCode = subsCode == null ? "" : subsCode;
        equipmentName = StringUtils.isEmpty(equipmentName) ? "" : equipmentName;
        Map<String, Object> resultMap = new HashMap<>();
        String SMSMessage ="";
        Map<String, Object> param = new HashMap<>();
        param.put("Time", endDate);
        param.put("position", installationPosition);
        param.put("IMEI", imei);
        param.put("phone", phone);
        param.put("address", address);
        param.put("subsName", custName);
        SMSMessage = Constants.RUNNING_SMS_SERVICE_PERIOD.replace("#verb#", verb)
                .replace("#Time#", endDate + "")
                .replace("#position#", installationPosition + "")
                .replace("#phone#", phone)
                .replace("#subsName#", custName)
                .replace("#address#", address)
                .replace("#IMEI#", imei);

        Map<String, Object> wxParam = new HashMap<>();
        String wxMessage ="";
        //微信模板消息 WARNING_WX_SERVICE_PERIOD
        wxMessage = Constants.WARNING_WX_SERVICE_PERIOD.replace("#verb#", verb)
                .replace("#Time#", endDate + "")
                .replace("#IMEI#", imei)
                .replace("#subsName#", custName)
                .replace("#subsCode#", subsCode)
                .replace("#address#", address);
        wxParam.put("Time", endDate);
        wxParam.put("position", installationPosition);
        wxParam.put("IMEI", imei);
        wxParam.put("Equipment_status", "报警");
        wxParam.put("phone", phone);
        wxParam.put("EquipmentName", equipmentName + "");
        wxParam.put("Name", name);
        wxParam.put("UserID", userID);
        wxParam.put("address", address.length() < 20 ? address : address.substring(0, 20));
        wxParam.put("subsName", custName.length() < 20 - subsCode.length() ? custName : custName.substring(0, 15 - subsCode.length()) + "...");
        wxParam.put("subsCode", subsCode);
        resultMap.put("SMSMessage", SMSMessage);
        resultMap.put("param", param);
        resultMap.put("wxParam", wxParam);
        resultMap.put("wxMessage", wxMessage);
        log.info("SMSMessage:{}wxMessage:{}", param, wxParam);
        return resultMap;
    }

    //存储报警记录
    public void saveWarningRecord(String spId, String iMEI,
                                  int report, String con, Object strategyId,
                                  String level, Date date, int sendType, long snowflakeId, int sendResult,
                                  String content, String supIMEI, Object errorMsg,
                                  String receiptCode, String telephone, int type, String info) {
        if (iMEI.contains("-")){
            String[] split = iMEI.split("-");
            if (split.length>=3) iMEI=split[0]+"-"+split[1]+"-"+split[2];
        }
        if (report==2){
            saveRunningRecord(spId,iMEI,report,con,strategyId,level,date,sendType,snowflakeId,
                    sendResult,content,supIMEI,errorMsg ,receiptCode,telephone,type,info);
        }else {
            InformRecord warningRecord = new InformRecord();
            warningRecord.setConsumerId(con);
            warningRecord.setStartTime(date);
            warningRecord.setTriggerRuleId(Long.parseLong(strategyId + ""));
            warningRecord.setIMEI(iMEI);
            warningRecord.setTaskIdentificationCode(snowflakeId + "");
            warningRecord.setSendType(sendType);
            warningRecord.setObjLevel(level);
            warningRecord.setSpId(spId);
            warningRecord.setSendResult(sendResult);
            warningRecord.setContent(content);
            warningRecord.setReceiptCode(receiptCode);
            warningRecord.setPushPhone(telephone);
            warningRecord.setRemark(!StringUtils.isEmpty(errorMsg) ? errorMsg + "" : "发送成功");
            log.info("saveWarningRecord:{}", JSONObject.toJSONString(warningRecord));
            informRecordMapper.insert(warningRecord);
        }


    }


    private Map<String, Object> sendWxMessage(Integer sendInterval, Date date, RunningStrategyExt ext,
                                              Map<String, Object> param, Map<String, Object> dataMap, Map<String, Object> dtuMap
            , String iMEI, int report, String con, Object strategyId, long snowflakeId, String content,
                                              String supIMEI, int type) {
        Map<String, Object> res = null;
        try {
            res = new HashMap<>();
            res.put("res", true);
            if (StringUtils.isEmpty(sendInterval) || ext == null) {
                res.put("res", "no");
                return res;
            }
            Map<String, Long> map = sendTimeAndSend(ext, date, sendInterval);
            Long send = map.get("send");
            Long nextSendTime = map.get("nextSendTime");
            if (send==1) {
                pushWx(param, dtuMap.get("sp_id") + "", iMEI, report, con, strategyId, date, snowflakeId, content, supIMEI,
                        dtuMap.get("cust_name") + "", dtuMap.get("subs_code") + "",
                        new ArrayList<>(), type, ext.getPushLevel());
            }else {
                res.put("res", "no");
            }
            dataMap.put("nextWxTime", nextSendTime);
        } catch (Exception e) {
            log.error("sendWxMessage-error:{}", e);
        }
        return res;
    }

    private Map<String, Object> sendMessage(Integer sendInterval, List<Map<String, Object>> list, RunningStrategyExt ext
            , Map<String, Object> dataMap, Date date, Map<String, Object> param,
                                            String spId, String iMEI, int report, String con, Object strategyId,
                                            long snowflakeId, String content, String supIMEI, String info,String key) {
        Map<String, Object> res = null;
        try {
            res = new HashMap<>();
            res.put("res", true);
            res.put("receiptCode", "");
            if (StringUtils.isEmpty(sendInterval) || ext == null) {
                res.put("res", "no");
                return res;
            }
            Map<String, Long> map = sendTimeAndSend(ext, date, sendInterval);
            Long send = map.get("send");
            Long nextSendTime = map.get("nextSendTime");
            if (send==1L) {
                Map<String, String> s = sendSms(list, ext, param, spId, iMEI,
                        report, con, strategyId, snowflakeId, content, supIMEI
                        , date, info);
                res.put("errorMsg", s.get("errorMsg"));
                if (!StringUtils.isEmpty(s.get("receiptCode"))) res.put("receiptCode", s.get("receiptCode"));
                dataMap.put("phone", s);//实际发送手机号,和实际发送级别绑定
            }else {
                res.put("res", "no");
            }
            dataMap.put("nextSendTime", nextSendTime);
        } catch (Exception e) {
            log.error("runningSendMessage-error:{}", e);
        }
        return res;
    }


    private Map<String, Long> sendTimeAndSend(RunningStrategyExt ext, Date date, Integer sendInterval) {
        Map<String, Long> map = new HashMap<>();
        Long nextSendTime = 0L;
        Long send = 0L;
        DtuPushTypeEnum pushTypes = DtuPushTypeEnum.getPushTypes(ext.getPushTime());
        if (ext.getPushTime() != 0) {
            Integer[] integers = pushTypes.getIntegers();
            int hours = date.getHours();
            if (hours > integers[1]) {
                nextSendTime = nextSendTime(sendInterval, date, pushTypes);
            } else if (hours < integers[0]) {
                nextSendTime = nextSendTime(sendInterval, DateUtil.offsetDay(date, -1), pushTypes);
            } else {
                //立马发
                nextSendTime = nextSendTime(sendInterval, date, pushTypes);
                send = 1L;
            }
        } else {
            //立马发
            send = 1L;
            nextSendTime = nextSendTime(sendInterval, date, pushTypes);
        }
        map.put("nextSendTime", nextSendTime);
        map.put("send", send);
        return map;
    }

    private long nextSendTime(Integer sendInterval, Date date, DtuPushTypeEnum pushTypes) {
        Date parse = pushTypes.getTypes().length > 1 ? DateUtil.parse(DateUtil.format(date, "yyyy-MM-dd") + pushTypes.getTypes()[0]) : date;
        if (sendInterval == 1) {
            DateTime dateTime = DateUtil.offsetDay(parse, 1);
            return dateTime.getTime();
        } else if (sendInterval == 2) {
            DateTime dateTime = DateUtil.offsetDay(parse, 7);
            return dateTime.getTime();
        } else if (sendInterval == 3) {
            DateTime dateTime = DateUtil.offsetMonth(parse, 1);
            return dateTime.getTime();
        }
        return 0L;
    }


    private Map<String, Object> callMessage(Integer callInterval, List<Map<String, Object>> list, RunningStrategyExt ext
            , Map<String, Object> dataMap, Date date, String spId, String iMEI,
                                            int report, String con, Object strategyId, long snowflakeId,
                                            String supIMEI, String info, String dtuType) {


        Map<String, Object> res = null;
        try {
            res = new HashMap<>();
            res.put("res", true);
            if (StringUtils.isEmpty(callInterval) || ext == null) {
                res.put("res", "no");
                return res;
            }
            Map<String, Long> map = sendTimeAndSend(ext, date, callInterval);
            Long send = map.get("send");
            Long nextSendTime = map.get("nextSendTime");
            if (send==1) {
                callSms(list, ext, spId, iMEI,
                        report, con, strategyId, snowflakeId
                        , date, info, dtuType);
            }else {
                res.put("res", "no");
            }
            dataMap.put("nextCallTime", nextSendTime);
        } catch (Exception e) {
            log.error("callMessage-error:{}", e);
        }
        return res;
    }

    private void callSms(List<Map<String, Object>> list, RunningStrategyExt ext,
                         String spId, String iMEI, int report, String con, Object strategyId,
                         long snowflakeId, Date date, String info, String dtuType) {

        Map<String, Integer> objectTypeMap = new HashMap<>();
        Set<String> phones = new HashSet<>();
        try {
            log.info("callSms-发送手机号:{}", phones);
            String pushLevels = ext.getPushLevel();
            if (pushLevels != null && !"0".equals(pushLevels)){
                String[] split = pushLevels.contains(";")?pushLevels.split(";"):new String[]{pushLevels};
                for (String pushLevelString  : split) {
                    Integer  pushLevel = null;
                    try {
                        pushLevel = Integer.parseInt(pushLevelString);
                    } catch (Exception e) {
                        log.error("runningCallSms-pushLevel:{}",e);
                        continue;
                    }
                    for (Map<String, Object> stringObjectMap : list) {
                        log.info("runningCallSms-level:{}", Integer.parseInt(stringObjectMap.get("level") + ""));
                        log.info("runningCallSms-pushLevel:{}", pushLevel);
                        if (Integer.parseInt(stringObjectMap.get("level") + "")
                                == pushLevel || pushLevel.equals(stringObjectMap.get("level"))) {
                            String telephone = stringObjectMap.get("telephone") + "";
                            if (!StringUtils.isEmpty(telephone)) {
                                phones.add(telephone);
                            }
                        }
                    }
                }
            }

            log.info("callSms-发送手机号:{}", phones);
            if (!CollectionUtils.isEmpty(phones)) {
                if ("Gas_alarm_controller".equals(dtuType) && iMEI.contains("-")) {
                    iMEI = iMEI.split("-")[0];
                }
                Map<String,Object> qMap = new HashMap<>();
                qMap.put("spId", spId);
                qMap.put("paramCode", OUTBOUND_CALL_CHANNEL_SETTINGS);
                List<BusinessNotice> noticeList = noticeMapper.selectParamList(qMap);
                if (!CollectionUtils.isEmpty(noticeList)) {
                    BusinessNotice businessNotice = noticeList.get(0);
                    if (StringUtils.pathEquals("ON", businessNotice.getParamValue())) {
                        Map<String, Object> map = callTaskService.sendCallTask(spId, phones, iMEI,report,con,ext);
                        String errMsg = null==map.get("errMsg")?"":map.get("errMsg").toString();
                        callTaskService.saveCallInformList((JSONArray) map.get("data"), (Map<String, Object>) map.get("dtuInfos"),
                                (Map<String, Object>) map.get("paramMap"),
                                (List<String>) map.get("phoneList"), spId, iMEI, 0, report, con, strategyId, pushLevels, date,
                                3, snowflakeId, StringUtils.isEmpty(errMsg)?2:1, iMEI, info, objectTypeMap, report, (String) map.get("robotContent"),
                                errMsg
                        );
                    }
                }
            }
        } catch (Exception e) {
            log.error("callSms-error:{}", e);
        }
    }


    private Map<String, String> sendSms(List<Map<String, Object>> list, RunningStrategyExt ext, Map<String, Object> param,
                                        String spId, String iMEI, int report, String con, Object strategyId, long snowflakeId,
                                        String content, String supIMEI, Date date, String info) {


        log.info("runningSendSms-param:{},{}", JSONObject.toJSONString(list), JSONObject.toJSONString(ext));
        Map<String, String> sendSms = new HashMap<>();
        AtomicReference<String> phoneAtomic = new AtomicReference<>();

        try {
            String pushLevels = ext.getPushLevel();
            if (pushLevels != null && !"0".equals(pushLevels)){
                String[] split = pushLevels.contains(";")?pushLevels.split(";"):new String[]{pushLevels};

//            if (pushLevel != null || pushLevel != 0) {
//                //走客户联系人
//                if (!CollectionUtil.isEmpty(list)) {
//                    List<Integer> objs = new ArrayList<>();
//                    list.forEach(stringObjectMap -> {
//                        objs.add(Integer.parseInt(stringObjectMap.get("level") + ""));
//                    });
//                    if (!objs.contains(pushLevel)) {
//                        List<Map<String, Object>> listCopy = new ArrayList<>();
//                        for (Map<String, Object> map : list) {
//                            if (pushLevel > Integer.parseInt(map.get("level") + "")) {
//                                listCopy.add(map);
//                            }
//                        }
//                        if (CollectionUtil.isEmpty(listCopy)) {
//                            log.info("runningSendSms-pushLevel，此级别没有合适的下级发送人：{}，客户id:{}"
//                                    , pushLevel, con);
//                        } else {
//                            listCopy.sort((o1, o2) -> {
//                                return -Integer.parseInt(o1.get("level") + "")
//                                        + Integer.parseInt(o2.get("level") + "");
//                            });
//                            pushLevel = Integer.parseInt(listCopy.get(0).get("level") + "");
//                        }
//                    }
                for (String pushLevelString  : split) {
                    Integer  pushLevel = null;
                    try {
                        pushLevel = Integer.parseInt(pushLevelString);
                    } catch (Exception e) {
                        log.error("runningSendSms-pushLevel:{}",e);
                        continue;
                    }
                    for (Map<String, Object> stringObjectMap : list) {
                        log.info("runningSendSms-level:{}", Integer.parseInt(stringObjectMap.get("level") + ""));
                        log.info("runningSendSms-pushLevel:{}", pushLevel);
                        if (Integer.parseInt(stringObjectMap.get("level") + "")
                                == pushLevel || pushLevel.equals(stringObjectMap.get("level"))) {
                            String telephone = stringObjectMap.get("telephone") + "";
                            if (!StringUtils.isEmpty(telephone)) {
                                String objInfo = info;
                                if (pushSMS(param, sendSms, phoneAtomic, telephone, "sms", spId, iMEI,
                                        report, con, strategyId, pushLevelString, snowflakeId, content, supIMEI, date,
                                        0, objInfo)) continue;
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            log.error("sendSms-error:{}", e);
            return sendSms;
        }

        if (phoneAtomic.get() == null) {
            return sendSms;
        } else {
            sendSms.put("phone", phoneAtomic.get());
            return sendSms;
        }
    }

    private boolean pushSMS(Map<String, Object> param, Map<String, String> sendSms,
                            AtomicReference<String> phoneAtomic,
                            String telephone, String msgType, String spId, String iMEI,
                            int report, String con, Object strategyId,
                            String level, long snowflakeId,
                            String content, String supIMEI, Date date, int type, String notifyObjInfo) {
        //给他发
        try {
            ValueOperations valueOperations = redisTemplate.opsForValue();
            Object o = valueOperations.get(Constants.WARNING_PHONE_RUNNING + "-" + telephone);
            log.info("running-获取发送次数:{}:{}", telephone, o);
            if (o != null && Integer.parseInt(o + "") >= 50) {
                sendSms.put("phone", phoneAtomic.get());
                sendSms.put("errorMsg", "此手机超过24小时发送次数");
                saveWarningRecord(spId, iMEI, report, con, strategyId,
                        level, date, 1, snowflakeId, 1, content,
                        supIMEI, "此手机超过24小时发送次数", sendSms.get("receiptCode"), telephone, type, notifyObjInfo);
                return true;
            }

            log.info("running-本次发送短信内容:{}:{}msgType:{}", telephone, param, msgType);
            if (StringUtils.isEmpty(telephone)) {
                saveWarningRecord(spId, iMEI, report, con, strategyId,
                        level, date, 1, snowflakeId, 1, content,
                        supIMEI, "手机号不能为空", "", telephone, type, notifyObjInfo);
                return false;
            }
            //调用外部短信接口
            String orgCode = companyService.getOrgCode(spId, con);
            Map<String, Object> sms = sendMessageService
                    .sendSms(sendMessageService
                                    .getRequestParam(telephone
                                            , SMSTypeEnum.getPushTypes(report).getName(), orgCode
                                            , param, msgType, null, null, null, 0)
                            , "");
            Object errorMsg = null;
            try {
                if (sms.get("result") != null && sms.get("result").equals(true)) {
                    Integer count = 1;
                    if (o != null) {
                        count = Integer.parseInt(o + "") + 1;
                    }
                    valueOperations.set(Constants.WARNING_PHONE_RUNNING + "-" + telephone
                            , count, 1L, TimeUnit.DAYS);
                }else{
                    errorMsg = null==sms.get("errMsg")?"":sms.get("errMsg");
                }
                if (sms.get("data") != null) {
                    log.info("running—短信发送人；{}", telephone);
                    HashMap<String, Object> req = new HashMap<>();
                    req.put("ids", sms.get("data"));
                    req.put("orgCode", orgCode);
                    try {
                        Map<String, Object> map = sendMessageService.subTaskDetail(req, "");
                        if (map != null) errorMsg = map.get("errorMsg");
                    } catch (Exception e) {
                        log.info("subTaskDetail-error:{}", e);
                    }
                    if (errorMsg != null) sendSms.put("errorMsg", errorMsg + "");
                    log.info("sendSms-发送remark:{}", errorMsg);
                    sendSms.put("receiptCode", JSONObject.toJSONString(sms.get("data")));
                } else {
                    errorMsg = sms.get("errMsg");
                }
                //查询短信内容
                TaskDetailParamDTO smsTaskDetailParam = new TaskDetailParamDTO();
                smsTaskDetailParam.setSpId(spId);
                smsTaskDetailParam.setOrgCode(orgCode);
                smsTaskDetailParam.setCode(SMSTypeEnum.getPushTypes(report).getName());
                TaskDetailRespDTO smsTaskDetailResp = sendMessageService.getMsgTemplateContent(smsTaskDetailParam);
                content = smsTaskDetailResp.getTemplateContent();
            } catch (Exception e) {
                log.error("running-error:{}", e);
            }
            saveWarningRecord(spId, iMEI, report, con, strategyId,
                    level, date, 1, snowflakeId, !StringUtils.isEmpty(errorMsg) ? 1 : 0, content,
                    supIMEI, errorMsg, StringUtils.isEmpty(sms.get("data")) ? "" : sms.get("data") + "", telephone, type, notifyObjInfo);

            log.info("sendSms-发送日志:{}回执消息:{},处理结果：{}", telephone, JSONObject.toJSONString(sms),
                    JSONObject.toJSONString(sendSms));
            phoneAtomic.set(telephone + "");
        } catch (Exception e) {
            log.error("running-error:{}", e);
        }
        return false;
    }

    public void updateRecordStatus(String imei, String taskIdentificationCode, int status) {
        InformRecord warningRecord = new InformRecord();
        warningRecord.setTaskIdentificationCode(taskIdentificationCode);
        warningRecord.setEndTime(new Date());
        warningRecord.setStatus(status);
        QueryWrapper<InformRecord> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().or()
                .eq(InformRecord::getTaskIdentificationCode, taskIdentificationCode);
        informRecordMapper.update(warningRecord, queryWrapper);
    }


    //告警
    public String getSmsWarningTemplate(Map<String, Object> param, String smsContent) {
        return smsContent.replace("#verb#", param.get("verb") + "")
                .replace("#Time#", param.get("Time") + "")
                .replace("#Date#", param.get("Date") + "")
                .replace("#value#", param.get("value") + "")
                .replace("#position#", param.get("position") + "")
                .replace("#Equipmenttype#", param.get("Equipmenttype") + "")
                .replace("#subsName#", param.get("subsName") + "")
                .replace("#address#", param.get("address") + "")
                .replace("#IMEI#", param.get("IMEI") + "")
                .replace("#phone#", param.get("Name") + "");

    }
}